package com.core.ingenium.model;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;
import javax.persistence.Query;


public class JavaServiceFacadeEPadilla extends JavaServiceFacade {
    
    private static final boolean isAutoCommit = true;
    private final EntityManagerHelper entityManagerHelper;
    
    public JavaServiceFacadeEPadilla() {
        super();
        entityManagerHelper = new EntityManagerHelper("Model", isAutoCommit);
    }
    
    //METODOS DE EPADILLA
       /** <code>select o from Rol o where o.descripcion like :pdescripcion</code> */
    public Rol getRolFindByDescripcion(Rol rol){
        Query q = entityManagerHelper.getEntityManager().createNamedQuery("Rol.findByDescripcion");
        q.setParameter("pdescripcion", "%"+rol.getDescripcion()+"%");
        return (Rol)q.getSingleResult();
    }

    /** <code>select o from Usuario o where o.nombreUsuario = :pnombreUsuario o</code> */
    public Usuario getUsuarioFindByName(Usuario usuario){
        Query q = entityManagerHelper.getEntityManager().createNamedQuery("Usuario.findByName");
        q.setParameter("pnombreUsuario", "%"+usuario.getNombreUsuario()+"%");
        return (Usuario)q.getSingleResult();
    }
    
    /** <code>select o from Usuario o where o.nombre like :pfiltro or o.apellido1 like :pfiltro or o.apellido2 like :pfiltro</code> */
    public List<Usuario> getUsuarioFindByFiltro(Usuario usuario){
        Query q = entityManagerHelper.getEntityManager().createNamedQuery("Usuario.findByFiltro");
        q.setParameter("pfiltro", "%"+usuario.getNombre()+"%");
        return (List)q.getResultList();
    }
    
    
    /** <code>select o from UsuarioCarrera o where o.usuario.id = :pid</code> */
    public UsuarioCarrera getUsuarioCarrerafindByUsuarioId(Usuario usuario){
        Query q = entityManagerHelper.getEntityManager().createNamedQuery("UsuarioCarrera.findByUsuarioId");
        q.setParameter("pid", usuario.getId());
        return (UsuarioCarrera)q.getSingleResult();
    }
    
    
    /** <code>UPDATE Usuario o SET o.clave = :pclave WHERE o.id = :pid</code> */
    public int usuarioUpdateClave(Usuario usuario){
        Query q = entityManagerHelper.getEntityManager().createNamedQuery("Usuario.updateClave");
        q.setParameter("pclave", "%"+usuario.getClave()+"%");
        q.setParameter("pid", usuario.getId());
        int num = q.executeUpdate();
        return num;
    }

    /** <code>select o from Estudiante o where o.nombre like :pfiltro or o.apellido1 like :pfiltro or o.apellido2 like :pfiltro</code> */
    public List<Estudiante> getEstudianteFindByFiltro(Estudiante estudiante){
        Query q = entityManagerHelper.getEntityManager().createNamedQuery("Estudiante.findByFiltro");
        q.setParameter("pfiltro", "%"+estudiante.getNombre()+"%");
        return (List)q.getResultList();
    }

    /** <code>select o from CarreraNivel o where o.codigo = :pcodigo</code> */
    public CarreraNivel getCarreraNivelFindByCodigo(CarreraNivel carreraNivel){
        Query q = entityManagerHelper.getEntityManager().createNamedQuery("CarreraNivel.findByCodigo");
        q.setParameter("pcodigo", "%"+carreraNivel.getCodigo()+"%");
        return (CarreraNivel)q.getSingleResult();
    }

    /** <code>select o from CarreraNivel o where o.id = :pid</code> */
    public CarreraNivel getCarreraNivelFindById(CarreraNivel carreraNivel){
        Query q = entityManagerHelper.getEntityManager().createNamedQuery("CarreraNivel.findById");
        q.setParameter("pid", carreraNivel.getId());
        return (CarreraNivel)q.getSingleResult();
    }
    
    /** <code>select o from Carrera o where o.id = :pid</code> */
    public Carrera getCarreraFindById(Carrera carrera){
        Query q = entityManagerHelper.getEntityManager().createNamedQuery("Carrera.findById");
        q.setParameter("pid", carrera.getId());
        return (Carrera)q.getSingleResult();
    }
    
    /** <code>select o from Rol o where o.id like :pid</code> */
    public Rol getRolFindById(Rol rol){
        Query q = entityManagerHelper.getEntityManager().createNamedQuery("Rol.findById");
        q.setParameter("pid", rol.getId());
        return (Rol)q.getSingleResult();
    }
    
    
    private class EntityManagerHelper {
        
        final private EntityManagerFactory _entityManagerFactory;
        final private boolean _isAutoCommit;

        private EntityManager _entityManager;

        EntityManagerHelper(String persistenceUnit, boolean isAutoCommit) {
            _entityManagerFactory = Persistence.createEntityManagerFactory(persistenceUnit);
            _isAutoCommit = isAutoCommit;
        }

        public EntityManager getEntityManager() {
            if (_entityManager == null) {
                _entityManager = _entityManagerFactory.createEntityManager();
            }

            return _entityManager;
        }

        public EntityTransaction getEntityTransaction() {
            return getEntityManager().getTransaction();
        }

        public void commitTransaction() {
            final EntityTransaction entityTransaction = getEntityTransaction();
            if (entityTransaction.isActive()) {
                entityTransaction.commit();
            }

            _closeEntityManager();
        }

        public void rollbackTransaction() {
            final EntityTransaction entityTransaction = getEntityTransaction();
            if (entityTransaction.isActive()) {
                entityTransaction.rollback();
            }

            _closeEntityManager();
        }

        public boolean isTransactionDirty() {
            return (!_isAutoCommit && getEntityTransaction().isActive());
        }

        public Object persistEntity(Object entity) {
            _beginTransactionIfNeeded();
            _entityManager.persist(entity);
            _commitTransactionIfNeeded();

            return entity;
        }

        public Object mergeEntity(Object entity) {
            _beginTransactionIfNeeded();
            entity = _entityManager.merge(entity);
            _commitTransactionIfNeeded();

            return entity;
        }

        public void removeEntity(Object entity) {
            _beginTransactionIfNeeded();
            _entityManager.remove(entity);
            _commitTransactionIfNeeded();
        }
        
        public void refreshEntity(Object entity){
            _beginTransactionIfNeeded();
            _entityManager.refresh(entity);
            _commitTransactionIfNeeded();
        }

        private void _beginTransactionIfNeeded() {
            final EntityTransaction entityTransaction = getEntityTransaction();
            if (!entityTransaction.isActive()) {
                entityTransaction.begin();
            }
        }

        private void _commitTransactionIfNeeded() {
            if (_isAutoCommit) {
                commitTransaction();
            }
        }

        private void _closeEntityManager() {
            if (_entityManager != null && _entityManager.isOpen()) {
                _entityManager.close();
            }

            _entityManager = null;
        }
    }
}
